package io.shuttle.mbe.api

import io.shuttle.mbe.api.annotation.ChromeMinVersion
import io.shuttle.mbe.api.annotation.PromiseStyleMinVersion
import io.shuttle.mbe.api.types.StringOrNumber
import io.shuttle.mbe.api.types.Value2Function
import io.shuttle.mbe.api.types.VoidFunction
import io.shuttle.mbe.core.Promise
import kotlinx.serialization.SerialName

////////////////////
// Context Menus
////////////////////
/**
 * Use the `Browser.contextMenus` API to add items to Google Chrome's context menu. You can choose what types of objects your context menu additions apply to, such as images, hyperlinks, and pages.
 *
 * Permissions: "contextMenus"
 */
interface ContextMenus {
    // The maximum number of top level extension items that can be added to an extension action context menu.
    // Any items beyond this limit will be ignored. default is 6.
    val ACTION_MENU_TOP_LEVEL_LIMIT : Int

    // Creates a new context menu item. If an error occurs during creation, it may not be detected
    // until the creation callback fires; details will be in runtime.lastError.
    // @return The ID of the newly created item.
     fun create(
        createProperties: CreateProperties,
        callback: VoidFunction? = null
    ): StringOrNumber

    // Removes a context menu item.
    @PromiseStyleMinVersion(123)
     fun remove(
        // The ID of the context menu item to remove.
        menuItemId: StringOrNumber,
        callback: VoidFunction? = null
    ): Promise<Void>

    // Removes all context menu items added by this extension.
    @PromiseStyleMinVersion(123)
     fun removeAll(
        callback: VoidFunction? = null
    ): Promise<Void>

    // Updates a previously created context menu item.
    @PromiseStyleMinVersion(123)
     fun update(
        // The ID of the item to update.
        id: StringOrNumber,
        updateProperties: CreateProperties,
        callback: VoidFunction? = null
    ): Promise<Void>

    // The different contexts a menu can appear in.
    // Specifying 'all' is equivalent to the combination of all other contexts except for 'launcher'.
    // The 'launcher' context is only supported by apps and is used to add menu items
    // to the context menu that appears when clicking the app icon in the launcher/taskbar/dock/etc.
    // Different platforms might put limitations on what is actually supported in a launcher context menu.
    @ChromeMinVersion(44)
    enum class ContextType {
        all,
        page,
        frame,
        selection,
        link,
        editable,
        image,
        video,
        audio,
        launcher,

        @SerialName("browser_action")
        browserAction,

        @SerialName("page_action")
        pageAction,
        action
    }

    // Properties of the new context menu item.
    @ChromeMinVersion(123)
    data class CreateProperties(
        // The initial state of a checkbox or radio button: true for selected, false for unselected.
        // Only one radio button can be selected at a time in a given group.
        var checked: Boolean? = null,
        // List of contexts this menu item will appear in. Defaults to ['page'].
        var contexts: List<ContextType>? = null,
        // Restricts the item to apply only to documents or frames whose URL matches one of the given patterns.
        // For details on pattern formats, see Match Patterns.
        var documentUrlPatterns: List<String>? = null,
        // Whether this context menu item is enabled or disabled. Defaults to true.
        var enabled: Boolean? = null,
        // The unique ID to assign to this item. Mandatory for event pages.
        // Cannot be the same as another ID for this extension.
        var id: String? = null,
        // The ID of a parent menu item; this makes the item a child of a previously added item.
        var parentId: StringOrNumber? = null,
        // Similar to documentUrlPatterns, filters based on the src attribute of img, audio,
        // and video tags and the href attribute of a tags.
        var targetUrlPatterns: List<String>? = null,
        // The text to display in the item; this is required unless type is separator.
        // When the context is selection, use %s within the string to show the selected text.
        // For example, if this parameter's value is "Translate '%s' to Pig Latin" and
        // the user selects the word "cool", the context menu item for the selection is
        // "Translate 'cool' to Pig Latin".
        var title: String? = null,
        // The type of menu item. Defaults to normal.
        var type: ItemType? = ItemType.normal,
        // Whether the item is visible in the menu.
        var visible: Boolean? = null,
        // A function that is called back when the menu item is clicked.
        // This is not available inside of a service worker; instead,
        // you should register a listener for contextMenus.onClicked.
        var onclick: Value2Function<OnClickData, Tabs.Tab>? = null,
    )

    // Fired when a context menu item is clicked.
     val onClicked: Events.Event<Value2Function<OnClickData, Tabs.Tab>>


    @ChromeMinVersion(44)
    enum class ItemType {
        normal,
        checkbox,
        radio,
        separator
    }

    // Information sent when a context menu item is clicked.
    data class OnClickData(
        // A flag indicating the state of a checkbox or radio item after it is clicked.
        var checked: Boolean? = null,
        // A flag indicating whether the element is editable (text input, textarea, etc.).
        var editable: Boolean,
        // The ID of the frame of the element where the context menu was clicked, if it was in a frame.
        @ChromeMinVersion(51)
        var frameId: Number? = null,
        // The URL of the frame of the element where the context menu was clicked, if it was in a frame.
        var frameUrl: String? = null,
        // If the element is a link, the URL it points to.
        var linkUrl: String? = null,
        // One of 'image', 'video', or 'audio' if the context menu was activated on one of these types of elements.
        var mediaType: String? = null,
        // The ID of the menu item that was clicked.
        var menuItemId: StringOrNumber,
        // The URL of the page where the menu item was clicked. This property is not set if the
        // click occured in a context where there is no current page, such as in a launcher context menu.
        var pageUrl: String? = null,
        // The parent ID, if any, for the item clicked.
        var parentMenuItemId: StringOrNumber? = null,
        // The text for the context selection, if any.
        var selectionText: String? = null,
        // Will be present for elements with a 'src' URL.
        var srcUrl: String? = null,
        // A flag indicating the state of a checkbox or radio item before it was clicked.
        var wasChecked: Boolean? = null,
    )
}